package io.github.bomb.batch.config;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * BatchConfig
 * Spring Batch 配置类，定义 Job、Step 以及 Reader、Processor 和 Writer。
 * <p>
 * 使用场景：
 * - 用于批量任务的核心配置。
 * - 将一个完整的批处理任务拆分为多个独立步骤，便于管理和测试。
 */
@Configuration
@EnableBatchProcessing // 启用 Spring Batch 核心功能
public class BatchConfig {

	/**
	 * 定义批处理任务 Job。
	 *
	 * @param jobBuilderFactory Job 构建工厂，用于创建 Job 实例。
	 * @param step1             定义的批处理步骤。
	 * @return Job 实例。
	 */
	@Bean
	public Job importJob(JobBuilderFactory jobBuilderFactory, Step step1) {
		return jobBuilderFactory.get("importJob") // 定义 Job 名称
				.start(step1) // 设置 Job 的起始步骤
				.build(); // 构建 Job
	}

	/**
	 * 定义批处理步骤 Step。
	 *
	 * @param stepBuilderFactory Step 构建工厂。
	 * @param reader             数据读取器。
	 * @param processor          数据处理器。
	 * @param writer             数据写入器。
	 * @return Step 实例。
	 */
	@Bean
	public Step step1(StepBuilderFactory stepBuilderFactory,
					  ItemReader<String> reader,
					  ItemProcessor<String, String> processor,
					  ItemWriter<String> writer) {
		return stepBuilderFactory.get("step1") // 定义 Step 名称
				.<String, String>chunk(10) // 定义数据批次大小，每 10 条数据作为一组。
				.reader(reader) // 设置数据读取器。
				.processor(processor) // 设置数据处理器。
				.writer(writer) // 设置数据写入器。
				.build(); // 构建 Step
	}

	/**
	 * 数据读取器，模拟从内存中读取数据。
	 *
	 * @return ItemReader 实例。
	 */
	@Bean
	public ItemReader<String> reader() {
		return new ItemReader<String>() {
			private final List<String> data = IntStream.range(0, 5) // 模拟生成 1000 条数据。
					.mapToObj(i -> "Item-" + i) // 数据格式为 "Item-0", "Item-1", ...
					.collect(Collectors.toList());
			private final Iterator<String> iterator = data.iterator();

			@Override
			public String read() {
				return iterator.hasNext() ? iterator.next() : null; // 按顺序读取数据。
			}
		};
	}


	/**
	 * 数据处理器，将数据转换为小写。
	 *
	 * @return ItemProcessor 实例。
	 */
	@Bean
	public ItemProcessor<String, String> processor() {
		return String::toLowerCase; // 转换逻辑：将字符串转换为小写。
	}

	/**
	 * 数据写入器，将处理后的数据打印到控制台。
	 *
	 * @return ItemWriter 实例。
	 */
	@Bean
	public ItemWriter<String> writer() {
		return items -> items.forEach(System.out::println); // 输出到控制台
	}
}
